using System;
using System.Collections.Generic;
using UnityEngine;

public class DataToolManager : MonoBehaviour
{
    private static DataToolManager instance;
    public static DataToolManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<DataToolManager>();
                if (instance == null)
                {
                    GameObject go = new GameObject("DataToolManager");
                    instance = go.AddComponent<DataToolManager>();
                    DontDestroyOnLoad(go);
                }
                else
                {
                    DontDestroyOnLoad(instance.gameObject);
                }
            }
            return instance;
        }
    }

    private Dictionary<Type, object> dataToolCache = new Dictionary<Type, object>();
    private Queue<Type> loadOrder = new Queue<Type>();
    private const int CacheThreshold = 8;

    public T GetDataTool<T>() where T : MonoBehaviour
    {
        Type type = typeof(T);

        if (dataToolCache.ContainsKey(type))
        {
            return (T)dataToolCache[type];
        }

        T dataTool = CreateDataTool<T>();
        AddToCache(type, dataTool);
        return dataTool;
    }

    private T CreateDataTool<T>() where T : MonoBehaviour
    {
        GameObject go = new GameObject(typeof(T).Name);
        T dataTool = go.AddComponent<T>();
        go.transform.SetParent(transform);
        return dataTool;
    }

    private void AddToCache(Type type, object dataTool)
    {
        if (dataToolCache.Count >= CacheThreshold)
        {
            Type oldestType = loadOrder.Dequeue();
            if (dataToolCache.ContainsKey(oldestType))
            {
                Destroy((MonoBehaviour)dataToolCache[oldestType]);
                dataToolCache.Remove(oldestType);
            }
        }

        dataToolCache[type] = dataTool;
        loadOrder.Enqueue(type);
    }
}
